home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libmpeg_src.lha / mb_ordered.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-25  |  11.8 KB  |  518 lines

  1. /*  
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. /* This file contains C code to implement an ordered dither. */
  22.  
  23. #include <config.h>
  24. #include "video.h"
  25. #include "proto.h"
  26. #include "dither.h"
  27.  
  28. #define DITH_SIZE 16
  29.  
  30.  
  31. /* Structures used to implement macroblock ordered
  32.    dither algorithm.
  33. */
  34.  
  35. static unsigned char ***ditherPtr[DITH_SIZE];
  36.  
  37.  
  38. /*
  39.  *--------------------------------------------------------------
  40.  *
  41.  *  InitMBOrderedDither--
  42.  *
  43.  *    Structures intialized for ordered dithering. 
  44.  *
  45.  * Results:
  46.  *    None.
  47.  *
  48.  * Side effects:
  49.  *      None.
  50.  *
  51.  *--------------------------------------------------------------
  52.  */
  53.  
  54. void
  55. InitMBOrderedDither()
  56. {
  57.   unsigned char ****pos_2_cb;
  58.   unsigned char ***cb_2_cr;
  59.   unsigned char **cr_2_l;
  60.   int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
  61.   int i, j, pos;
  62.   int err_range, threshval;
  63.  
  64.   pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
  65.   cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
  66.   cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
  67.  
  68.   for (pos=0; pos<DITH_SIZE; pos++) {
  69.     
  70.     pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
  71.  
  72.     for (j=0; j<CB_RANGE; j++) {
  73.       cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
  74.     }
  75.  
  76.     for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
  77.       (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
  78.     }
  79.  
  80.     for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
  81.       err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
  82.       threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
  83.  
  84.       for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
  85.     if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
  86.     else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
  87.       }
  88.     }
  89.  
  90.     for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
  91.       (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
  92.     }
  93.  
  94.     for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
  95.       
  96.       for (j=0; j<CR_RANGE; j++) {
  97.     cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
  98.       }
  99.  
  100.       for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
  101.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
  102.       }
  103.  
  104.       for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
  105.     err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
  106.     threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
  107.     
  108.     for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
  109.       if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
  110.       else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
  111.     }
  112.       }
  113.       
  114.       for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
  115.     (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
  116.       }
  117.       
  118.       for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
  119.     
  120.     for (l_val = 0; l_val < lum_values[0]; l_val++) {
  121.       (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
  122.                         (0*CR_RANGE*CB_RANGE)];
  123.     }
  124.  
  125.     for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
  126.       err_range = lum_values[l_rval+1] - lum_values[l_rval];
  127.       threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
  128.  
  129.       for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
  130.         if (l_val>threshval) (cr_2_l[cr_rval])[l_val] = 
  131.           pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
  132.         else (cr_2_l[cr_rval])[l_val] =
  133.           pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
  134.       }
  135.     }
  136.  
  137.     for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
  138.       (cr_2_l[cr_rval])[l_val] = 
  139.         pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
  140.     }
  141.       }
  142.     }
  143.   }
  144.  
  145.   for (i=0; i<DITH_SIZE; i++) {
  146.     ditherPtr[i] = pos_2_cb[i];
  147.   }
  148. }
  149.  
  150.  
  151.  
  152. /*
  153.  *--------------------------------------------------------------
  154.  *
  155.  * MBOrderedDitherImage --
  156.  *
  157.  *    Dithers an image using an ordered dither at macroblock level.
  158.  *    Assumptions made:
  159.  *      1) The color space is allocated y:cr:cb = 8:4:4
  160.  *      2) The spatial resolution of y:cr:cb is 4:1:1
  161.  *      The channels are dithered based on the standard
  162.  *      ordered dither pattern for a 4x4 area. 
  163.  *
  164.  * Results:
  165.  *    None.
  166.  *
  167.  * Side effects:
  168.  *    None.
  169.  *
  170.  *--------------------------------------------------------------
  171.  */
  172. void
  173. MBOrderedDitherImage (lum, cr, cb, out, h, w)
  174.     unsigned char *lum;
  175.     unsigned char *cr;
  176.     unsigned char *cb;
  177.     unsigned char *out;
  178.     int h, w;
  179. {
  180.   unsigned char *l, *r, *b, *o1, *o2;
  181.   unsigned char *l2;
  182.   unsigned char L, R, B;
  183.   int i, j, mbaddr, mbwidth;
  184.   unsigned char ***dp0 = ditherPtr[0];
  185.   unsigned char ***dp2 = ditherPtr[2];
  186.   unsigned char ***dp4 = ditherPtr[4];
  187.   unsigned char ***dp6 = ditherPtr[6];
  188.   unsigned char ***dp8 = ditherPtr[8];
  189.   unsigned char ***dp10 = ditherPtr[10];
  190.   unsigned char ***dp12 = ditherPtr[12];
  191.   unsigned char ***dp14 = ditherPtr[14];
  192.   unsigned char ***dp1 = ditherPtr[1];
  193.   unsigned char ***dp3 = ditherPtr[3];
  194.   unsigned char ***dp5 = ditherPtr[5];
  195.   unsigned char ***dp7 = ditherPtr[7];
  196.   unsigned char ***dp9 = ditherPtr[9];
  197.   unsigned char ***dp11 = ditherPtr[11];
  198.   unsigned char ***dp13 = ditherPtr[13];
  199.   unsigned char ***dp15 = ditherPtr[15];
  200.  
  201.   l = lum;
  202.   l2 = lum + w;
  203.   r = cr;
  204.   b = cb;
  205.   o1 = out;
  206.   o2 = out+w;
  207.   mbwidth = w / 16;
  208.  
  209.   for (i=0; i<h; i+=4) {
  210.  
  211.     mbaddr = (i / 16) * mbwidth ;
  212.  
  213.     for (j=0; j<w; j+=8) {
  214.  
  215.       if (ditherFlags[mbaddr+(j/16)]) {
  216.     R = r[0]; B = b[0];
  217.     
  218.     L = l[0];
  219.     o1[0] = ((dp0[B])[R])[L];
  220.     L = l[1];
  221.     o1[1] = ((dp8[B])[R])[L];
  222.     L = l2[0];
  223.     o2[0] = ((dp12[B])[R])[L];
  224.     L = l2[1];
  225.     o2[1] = ((dp4[B])[R])[L];
  226.     
  227.     R = r[1]; B = b[1];
  228.     
  229.     L = l[2];
  230.     o1[2] = ((dp2[B])[R])[L];
  231.     L = l[3];
  232.     o1[3] = ((dp10[B])[R])[L];
  233.     L = l2[2];
  234.     o2[2] = ((dp14[B])[R])[L];
  235.     L = l2[3];
  236.     o2[3] = ((dp6[B])[R])[L];
  237.     
  238.     R = r[2]; B = b[2];
  239.     
  240.     L = l[4];
  241.     o1[4] = ((dp0[B])[R])[L];
  242.     L = l[5];
  243.     o1[5] = ((dp8[B])[R])[L];
  244.     L = l2[4];
  245.     o2[4] = ((dp12[B])[R])[L];
  246.     L = l2[5];
  247.     o2[5] = ((dp4[B])[R])[L];
  248.     
  249.     R = r[3]; B = b[3];
  250.     
  251.     L = l[6];
  252.     o1[6] = ((dp2[B])[R])[L];
  253.     L = l[7];
  254.     o1[7] = ((dp10[B])[R])[L];
  255.     L = l2[6];
  256.     o2[6] = ((dp14[B])[R])[L];
  257.     L = l2[7];
  258.     o2[7] = ((dp6[B])[R])[L];
  259.       }
  260.       
  261.       l += 8;
  262.       l2 += 8;
  263.       r += 4;
  264.       b += 4;
  265.       o1 += 8;
  266.       o2 += 8;
  267.     }
  268.     
  269.     l += w; l2 += w;
  270.     o1 += w; o2 += w;
  271.  
  272.     for (j=0; j<w; j+=8) {
  273.  
  274.       if (ditherFlags[mbaddr+(j/16)]) {
  275.  
  276.     R = r[0]; B = b[0];
  277.     
  278.     L = l[0];
  279.     o1[0] = ((dp3[B])[R])[L];
  280.     L = l[1];
  281.     o1[1] = ((dp11[B])[R])[L];
  282.     L = l2[0];
  283.     o2[0] = ((dp15[B])[R])[L];
  284.     L = l2[1];
  285.     o2[1] = ((dp7[B])[R])[L];
  286.     
  287.     R = r[1]; B = b[1];
  288.     
  289.     L = l[2];
  290.     o1[2] = ((dp1[B])[R])[L];
  291.     L = l[3];
  292.     o1[3] = ((dp9[B])[R])[L];
  293.     L = l2[2];
  294.     o2[2] = ((dp13[B])[R])[L];
  295.     L = l2[3];
  296.     o2[3] = ((dp5[B])[R])[L];
  297.     
  298.     R = r[2]; B = b[2];
  299.     
  300.     L = l[4];
  301.     o1[4] = ((dp3[B])[R])[L];
  302.     L = l[5];
  303.     o1[5] = ((dp11[B])[R])[L];
  304.     L = l2[4];
  305.     o2[4] = ((dp15[B])[R])[L];
  306.     L = l2[5];
  307.     o2[5] = ((dp7[B])[R])[L];
  308.     
  309.     R = r[3]; B = b[3];
  310.     
  311.     L = l[6];
  312.     o1[6] = ((dp1[B])[R])[L];
  313.     L = l[7];
  314.     o1[7] = ((dp9[B])[R])[L];
  315.     L = l2[6];
  316.     o2[6] = ((dp13[B])[R])[L];
  317.     L = l2[7];
  318.     o2[7] = ((dp5[B])[R])[L];
  319.       }
  320.  
  321.       l += 8;
  322.       l2 += 8;
  323.       r += 4;
  324.       b += 4;
  325.       o1 += 8;
  326.       o2 += 8;
  327.     }
  328.     
  329.     l += w; l2 += w;
  330.     o1 += w; o2 += w;
  331.   }
  332. }
  333.  
  334. void
  335. MBOrderedDitherDisplayCopy(vid_stream, mb_addr, motion_forw, r_right_forw,
  336.         r_down_forw, motion_back, r_right_back, r_down_back, past, future)
  337.     VidStream *vid_stream;
  338.     int mb_addr;
  339.     int motion_forw, r_right_forw, r_down_forw;
  340.     int motion_back, r_right_back, r_down_back;
  341.     unsigned char *past, *future;
  342. {
  343.   int right_back, right_forw, down_back, down_forw;
  344.   unsigned char *dest;
  345.   unsigned char *src1, *src2;
  346.   int row, col, row_size, rr;
  347.   int mc, mr;
  348.  
  349.   row = (mb_addr / vid_stream->mb_width) << 4;
  350.   col = (mb_addr % vid_stream->mb_width) << 4;
  351.   row_size = vid_stream->mb_width << 4;
  352.  
  353.   dest = vid_stream->current->display + (row * row_size) + col;
  354.  
  355.   if (motion_forw) {
  356.     right_forw = r_right_forw >> 1;
  357.     down_forw = r_down_forw >> 1;
  358.     src1 = past + ((row + down_forw) * row_size) + (col + right_forw);
  359.   }
  360.  
  361.   if (motion_back) {
  362.     right_back = r_right_back >> 1;
  363.     down_back = r_down_back >> 1;
  364.     src2 = future + ((row + down_back) * row_size) + (col + right_back);
  365.   }
  366.    
  367.   if (motion_forw) {
  368.     if (motion_back) {
  369.       for (rr = 0; rr<16; rr++) {
  370.     dest[0] = src1[0];    dest[1] = src2[1];
  371.     dest[2] = src1[2];    dest[3] = src2[3];
  372.     dest[4] = src1[4];    dest[5] = src2[5];
  373.     dest[6] = src1[6];    dest[7] = src2[7];
  374.     dest[8] = src1[8];    dest[9] = src2[9];
  375.     dest[10] = src1[10];    dest[11] = src2[11];
  376.     dest[12] = src1[12];    dest[13] = src2[13];
  377.     dest[14] = src1[14];    dest[15] = src2[15];
  378.  
  379.     dest += row_size;
  380.     src1 += row_size;
  381.     src2 += row_size;
  382.       }
  383.     }
  384.     else {
  385.       mc = col & 0x3;
  386.       mr = right_forw & 0x3;
  387.       if (!mc && !mr) {
  388.     /* Use 32 bit copy */
  389.     int *d, *s;
  390.  
  391.     d = (int *) dest;
  392.     s = (int *) src1;
  393.     row_size /= 4;
  394.     
  395.     for (rr = 0; rr < 16; rr++) {
  396.       d[0] = s[0];
  397.       d[1] = s[1];
  398.       d[2] = s[2];
  399.       d[3] = s[3]; 
  400.       d += row_size;
  401.       s += row_size;
  402.     }
  403.       } else if ((!mc || (mc == 2)) &&
  404.          (!mr || (mr == 2))) {
  405.     /* Use 16 bit copy */
  406.     short int *d, * s;
  407.     
  408.     d = (short int *) dest;
  409.     s = (short int *) src1;
  410.     row_size /= 2;
  411.     
  412.     for (rr = 0; rr < 16; rr++) {
  413.       d[0] = s[0];
  414.       d[1] = s[1];
  415.       d[2] = s[2];
  416.       d[3] = s[3]; 
  417.       d[4] = s[4];
  418.       d[5] = s[5];
  419.       d[6] = s[6];
  420.       d[7] = s[7]; 
  421.       d += row_size;
  422.       s += row_size;
  423.     }
  424.       }
  425.       else {
  426.     for (rr = 0; rr < 16; rr++) {
  427.       dest[0] = src1[0];
  428.       dest[1] = src1[1];
  429.       dest[2] = src1[2];
  430.       dest[3] = src1[3];
  431.       dest[4] = src1[4];
  432.       dest[5] = src1[5];
  433.       dest[6] = src1[6];
  434.       dest[7] = src1[7];
  435.       dest[8] = src1[8];
  436.       dest[9] = src1[9];
  437.       dest[10] = src1[10];
  438.       dest[11] = src1[11];
  439.       dest[12] = src1[12];
  440.       dest[13] = src1[13];
  441.       dest[14] = src1[14];
  442.       dest[15] = src1[15];
  443.       
  444.       dest += row_size;
  445.       src1 += row_size;
  446.     }
  447.       }
  448.     }
  449.   }
  450.   else if (motion_back) {
  451.     mc = col & 0x3;
  452.     mr = right_back & 0x3;
  453.     if (!mc && !mr) {
  454.       /* Use 32 bit copy */
  455.       int *d, *s;
  456.       
  457.       d = (int *) dest;
  458.       s = (int *) src2;
  459.       row_size /= 4;
  460.       
  461.       for (rr = 0; rr < 16; rr++) {
  462.     d[0] = s[0];
  463.     d[1] = s[1];
  464.     d[2] = s[2];
  465.     d[3] = s[3]; 
  466.     d += row_size;
  467.     s += row_size;
  468.       }
  469.     }
  470.     else if ((!mc || mc == 2) &&
  471.          (!mr || mr == 2)) {
  472.       /* Use 8 bit copy */
  473.       short int *d, *s;
  474.       
  475.       d = (short int *) dest;
  476.       s = (short int *) src2;
  477.       row_size /= 2;
  478.       
  479.       for (rr = 0; rr < 16; rr++) {
  480.     d[0] = s[0];
  481.     d[1] = s[1];
  482.     d[2] = s[2];
  483.     d[3] = s[3]; 
  484.     d[4] = s[4];
  485.     d[5] = s[5];
  486.     d[6] = s[6];
  487.     d[7] = s[7]; 
  488.     d += row_size;
  489.     s += row_size;
  490.       }
  491.     }
  492.     else {
  493.       for (rr = 0; rr < 16; rr++) {
  494.     /* Use 8 bit copy */
  495.     dest[0] = src2[0];
  496.     dest[1] = src2[1];
  497.     dest[2] = src2[2];
  498.     dest[3] = src2[3];
  499.     dest[4] = src2[4];
  500.     dest[5] = src2[5];
  501.     dest[6] = src2[6];
  502.     dest[7] = src2[7];
  503.     dest[8] = src2[8];
  504.     dest[9] = src2[9];
  505.     dest[10] = src2[10];
  506.     dest[11] = src2[11];
  507.     dest[12] = src2[12];
  508.     dest[13] = src2[13];
  509.     dest[14] = src2[14];
  510.     dest[15] = src2[15];
  511.     
  512.     dest += row_size;
  513.     src2 += row_size;
  514.       }
  515.     }
  516.   }
  517. }
  518.